package com.erp.service.util;

import java.lang.reflect.Type;
import java.util.Date;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.erp.service.entity.DotnetDateSerializer;
import com.erp.service.entity.DotnetDateDeserializer;
import com.erp.service.util.net.HttpParams;

/**
 * JSON序列化工具类
 *
 */
public class JSONHelper {
	/**
	 * GsonBuilder对象
	 */
	private static ParserConfig defaultConfig;
	
	static {
		defaultConfig = new ParserConfig() {
			@Override
			public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
				if (clazz == Date.class)
					return DotnetDateDeserializer.instance;
				return super.getDeserializer(clazz, type);
			}
		};
	}

	/**
	 * 反序列化JSON对象为指定的实体(一般反序列化.net序列化的json对象，内部对.net返回的日期类型进行处理)
	 * 
	 * @author ccl
	 * 
	 * @param <T>
	 *            实体类型
	 * @param returnType
	 *            实体的class，例如:UserEntity.class
	 * @param jsonObject
	 *            JSONObject对象
	 * @return 反序列化后的实体
	 */
	@Deprecated
	public static <T> T deserialize(Class<T> returnType, JSONObject jsonObject) {
		return JSON.<T>parseObject(jsonObject.toString(), returnType, defaultConfig, JSON.DEFAULT_PARSER_FEATURE);
	}

	/**
	 * 反序列化JSON对象为指定的实体
	 * 
	 * @author ccl
	 * 
	 * @param type
	 *            实体的class，例如:UserEntity.class
	 * @param jsonArray
	 *            JSONArray对象
	 * @return 反序列化后的实体
	 * @throws JSONException
	 * @throws JsonSyntaxException
	 */
	@Deprecated
	public static <T> List<T> deserialize(Type type, JSONArray jsonArray) {
		return JSON.parseArray(jsonArray.toString(), (Class<T>) type);
	}


	/**
	 * 反序列化JSON文本为指定的实体list
	 * 
	 * @author ccl
	 * 
	 * @param type
	 *            实体的class，例如:UserEntity.class
	 * @param json
	 *            json文本
	 * @return 反序列化后的实体list
	 * @throws JSONException
	 * @throws JsonSyntaxException
	 */
	public static <T> List<T> deserializeArray(Type type, String json) {
		return JSONHelper.parseArray(json, (Class<T>) type);
	}

	public static final <T> List<T> parseArray(String text, Class<T> clazz) {
		if (text == null) {
			return null;
		}

		List<T> list = new ArrayList<T>();
		DefaultJSONParser parser = new DefaultJSONParser(text, defaultConfig);
		parser.parseArray(clazz, list);
		parser.close();
		return list;
	}

	/**
	 * 反序列化 JSON文本为指定的对象javaBean对象
	 * serialize之后传送过去在使用此方法(fastjson)
	 * 
	 * @author ccl
	 * 
	 * @param json 
	 *              序列化后的josn文本
	 * @param returnType
	 *              实体的class，例如:UserEntity.class
	 *           
	 * @return 序列化后的JSON文本 

	 */
	public static <T> T deserialize(Type returnType, String json) {
		return JSON.<T>parseObject(json, returnType, defaultConfig, JSON.DEFAULT_PARSER_FEATURE);
	}

	/**
	 * 序列化指定的实体 JSON对象(fastjson)
	 * 
	 * @author ccl
	 * 
	 * @param object 
	 *             javaBean实体
	 *           
	 * @return 
	 *         序列化后的JSON文本 

	 */
	public static <T> String serialize(Object object) {
		SerializeConfig config = new SerializeConfig();
		config.put(Date.class, DotnetDateSerializer.instance);
		return JSON.toJSONString(object,config);
	}

    /**
     * 把数据源HashMap转换成json
     *
     * @param map
     */
    public static String hashMapToJson(Map<String, String> map) {
        if (map.size() > 0) {
            String string = "{";
            for (Iterator<?> it = map.entrySet().iterator(); it.hasNext();) {
                Map.Entry<String, String> e = (Map.Entry<String, String>) it.next();
                string += "'" + e.getKey() + "':";
                string += "'" + e.getValue() + "',";
            }
            string = string.substring(0, string.lastIndexOf(","));
            string += "}";
            return string;
        }else{
            return "";
        }
    }

	/**
	 * 将请求参数是name1=value1&name2=value2的形式的字符串转为键值对
	 *
	 * @param paramsString
	 *            {@link String} name1=value1&name2=value2形式的请求参数
	 * @return
	 */
	public static List<NameValuePair> toNameValuePairList(String paramsString) {
		List<NameValuePair> NameValuePairList = new ArrayList<NameValuePair>();
		if (paramsString != null && !paramsString.equals("")) {
			String[] paramsArray = paramsString.split("\\&");
			for (String param : paramsArray) {
				String[] keyValue = param.split("\\=");
				NameValuePairList.add(new BasicNameValuePair(keyValue[0],
						keyValue.length > 1 ? keyValue[1] : ""));
			}
		}
		return NameValuePairList;
	}

	/**
	 * 将键值对转化为name1=value1&name2=value2形式的字符串
	 *
	 * @param params
	 *            {@link List} 键值对
	 * @return
	 */
	public static String fromNameValuePairList(List<NameValuePair> params) {
		String result = "";

		for (NameValuePair nameValuePair : params) {
			result += nameValuePair.getName() + "=" + nameValuePair.getValue()
					+ "&";
		}
		if (result.endsWith("&"))
			result = result.substring(0, result.length() - 1);
		return result;
	}

    /**
     * 将数据源httpParams转换成json
     *
     * @param httpParams
     * @return
     */
    public static String httpParamsToJson(HttpParams httpParams) {
        List<NameValuePair> nameValuePairs = httpParams.toNameValuePairs();
        if (nameValuePairs.size() > 0) {
            String string = "{";
            for (int i = 0; i < nameValuePairs.size(); i++) {
                string += "'" + nameValuePairs.get(i).getName() + "':";
                string += "'" + nameValuePairs.get(i).getValue() + "',";
            }
            string = string.substring(0, string.lastIndexOf(","));
            string += "}";
            return string;
        } else {
            return "";
        }
    }

}